#!BPY

"""
Name: 'Dwarf3d Mesh (.dwarfmesh)'
Blender: 249
Group: 'Export'
Tooltip: 'Exports a Dwarf3D Mesh'
"""

import bpy
import Blender
from Blender import *
from Blender.Mathutils import *

##################################################################
# Define export functions
##################################################################

def writeHeader(name, file):
	file.write("# ------------\n")
	file.write("# Dwarf3D Mesh\n")
	file.write("# ------------\n")
	file.write("Version 1.0\n")
	file.write("Mesh %s\n" % name)
	file.write("\n")

def writeSectionHeader(label, count, file):
	file.write("# -----------------------------\n")
	file.write("  %s %d\n" % (label, count))
	file.write("# -----------------------------\n")
	
def writeVertexList(verts, normals, file):
	writeSectionHeader("Vertices", len(verts), file)
	for i in range(len(verts)):
		file.write("v %f %f %f %f %f %f\n" % (verts[i][0], verts[i][1], verts[i][2], normals[i][0], normals[i][1], normals[i][2]))
	file.write("\n")

def addToUVList(uv, list):
	for i in list:
		if round(uv[0], 6) == round(i[0], 6) and round(uv[1], 6) == round(i[1], 6):
			return
	list.append(uv)

def writeTextureUVList(mesh, file):
	uvs = []
	activeUVLayer = mesh.activeUVLayer
	for name in mesh.getUVLayerNames():
		mesh.activeUVLayer = name
		for face in mesh.faces:
			for i in face.uv:
				addToUVList(i, uvs)
	mesh.activeUVLayer = activeUVLayer

	file.write("TextureUVs %d\n" % len(uvs))
	for uv in uvs:
		file.write("\t%f %f\n" % (uv[0], uv[1]))
	

def writeFaceList(mesh, file):
	writeSectionHeader("Faces", len(mesh.faces), file)
	for face in mesh.faces:
		file.write("f %d %d %d %d %f %f %f\n" % (face.mat, face.verts[0].index, face.verts[1].index, face.verts[2].index, face.no[0], face.no[1], face.no[2]))
	file.write("\n")
		
def writeUVLayers(mesh, file):
	uvNames = mesh.getUVLayerNames()
	writeSectionHeader("UVLayers", len(uvNames), file)
	activeUVLayer = mesh.activeUVLayer
	
	for name in uvNames:
		file.write("UVLayer %s\n" % name)
		mesh.activeUVLayer = name
		for face in mesh.faces:
			for uv in face.uv:
				file.write("\tuv %f %f\n" % (uv[0], uv[1]));
				
	#Reset the mesh to use the originally active uv layer
	mesh.activeUVLayer = activeUVLayer

def writeTextures(mesh, file):
	writeSectionHeader("Textures", len(Texture.Get()), file)
	for tex in Texture.Get():
		if tex.getImage() != None:
			file.write("t %s %s\n" %(tex.getName(), tex.getImage().getFilename()))
	file.write("\n")
		
def writeMaterials(mesh, file):
	writeSectionHeader("Materials", len(mesh.materials), file)
	
	for mat in mesh.materials:
		print(mat.name)
		diffuse = mat.getRGBCol()
		specular = mat.getSpecCol()
		
		file.write("m %s\n" % mat.name)
		file.write("\tdiffuse %f %f %f\n" % (diffuse[0], diffuse[1], diffuse[2]))
		file.write("\tspecular %f %f %f\n" % (specular[0], specular[1], specular[2]))
		file.write("\tambient %f\n" % mat.getAmb())
		file.write("\temit %f\n" % mat.getEmit())
		
		for tex in mat.getTextures():
			if tex != None:
				print("UV Layer for %s = '%s'" % (tex.tex.getName(), tex.uvlayer))
				if tex.uvlayer == "" or tex.uvlayer == None:
					print("WARNING: Material has not specified a UV layer for texture %s.  Defaulting to %s" % (tex.tex.getName(), mesh.getUVLayerNames()[0]))
					file.write("\ttr %s %s\n" % (tex.tex.getName(), mesh.getUVLayerNames()[0]))
				else:
					file.write("\ttr %s %s\n" % (tex.tex.getName(), tex.uvlayer))
				if tex.blendmode == Texture.BlendModes.MIX:
					file.write("\t\tblend MIX %f\n" % tex.colfac)
				elif tex.blendmode == Texture.BlendModes.MULTIPLY:
					file.write("\t\tblend MULTIPLY %f\n" % tex.colfac);
		file.write("\n")
	
def export(filename):
	scene = Scene.GetCurrent()
	activeObj = scene.objects.active
	
	if activeObj == None:
		print("No mesh is currently selected.")
		return

	if activeObj.type == "Mesh":
		file = open(filename, "w")
		
		# Create a duplicate of the mesh which will be triangulated
		obj = Object.New('Mesh')
		obj.name = "dwarfmesh_tmp"
		mesh = Mesh.New('tmp')
		mesh.getFromObject(activeObj)
		obj.link(mesh)
		scene.link(obj)
		
		# Select all the faces in the mesh
		for face in mesh.faces:
			if len(face.verts) == 4:
				face.sel = 1	
		
		# Triangulate them
		mesh.quadToTriangle(0)
		
		# Rotate about the x axis so that y is up
		rotatedVerts = []
		rotatedNormals = []
		rotation = RotationMatrix(90, 3, "x");
		for vert in mesh.verts:
			rotatedVerts.append(rotation * vert.co)
			rotatedNormals.append(rotation * vert.no)
		
		writeHeader(activeObj.name, file)
		writeTextures(mesh, file)
		if mesh.faceUV == True:
			writeUVLayers(mesh, file)
		writeMaterials(mesh, file)
		writeVertexList(rotatedVerts, rotatedNormals, file)
		writeFaceList(mesh, file)

		file.close()
		scene.objects.unlink(obj)
	else:
		print("Please select a mesh.")
#"""
#	 * MIX - mix texture with value
#    * MULTIPLY - multiply texture with value
#    * ADD - add texture to value
#    * SUBTRACT - subtract texture from value
#    * DIVIDE - divide value by texture
#    * DARKEN - replace value with texture if texture is darker
#    * DIFFERENCE - difference of texture from value
#    * LIGHTEN - replace value with texture if texture is lighter
#    * SCREEN - 'screen' mode
#"""
				
##################################################################
# Export the mesh
##################################################################



Window.FileSelector(export, 'Export Mesh', Scene.GetCurrent().objects.active.name + ".dwarfmesh")
#export("C:/dev/projects/citybuilder/resources/meshes/com_office.dwarfmesh")
